package com.markby.fscm.cryptogram.domain.standard0018;

import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;

import java.nio.ByteOrder;

import static com.markby.fscm.cryptogram.domain.standard0016.Constant0016.ECC_MAX_XCOORDINATE_BITS_LEN;
import static com.markby.fscm.cryptogram.domain.standard0016.Constant0016.ECC_MAX_YCOORDINATE_BITS_LEN;
import static com.markby.fscm.cryptogram.domain.standard0018.Constant0018.ECCref_MAX_LEN;
import static com.markby.fscm.cryptogram.uitls.HexUtils.intToBytes;


/**
 * 0018-2023规范 ECC公钥数据结构
 * ULONG 为32位无符号整数
 * typedef struct ECCrefPublicKey_st
 * {
 * ULONG bits;					// 密钥位长（4字节）
 * BYTE x[ECCref_MAX_LEN];		// 公钥x坐标（ECCref_MAX_LEN字节）
 * BYTE y[ECCref_MAX_LEN];		// 公钥y坐标（ECCref_MAX_LEN字节）
 * }ECCrefPublicKey;
 */
public class ECCrefPublicKey {

    private int bits;
    private byte[] x;
    private byte[] y;

    public ECCrefPublicKey(int ulBits, byte[] x, byte[] y) {
        if (x.length != ECCref_MAX_LEN) {
            throw new IllegalArgumentException("Invalid XCoordinate length: " + x.length);
        }
        if (y.length != ECCref_MAX_LEN) {
            throw new IllegalArgumentException("Invalid YCoordinate length: " + y.length);
        }
        this.bits = ulBits;
        this.x = x;
        this.y = y;
    }

    public ECCrefPublicKey(BCECPublicKey encPubKey, int ulBits) {
        byte[] XBytes = encPubKey.getW().getAffineX().toByteArray();
        byte[] YBytes = encPubKey.getW().getAffineY().toByteArray();

//        if (XBytes.length > ECC_MAX_XCOORDINATE_BITS_LEN / 8) {
//            throw new IllegalArgumentException("Invalid X length: " + XBytes.length);
//        }
//        if (YBytes.length > ECC_MAX_YCOORDINATE_BITS_LEN / 8) {
//            throw new IllegalArgumentException("Invalid Y length: " + YBytes.length);
//        }
        x = new byte[ECC_MAX_XCOORDINATE_BITS_LEN / 8];
        y = new byte[ECC_MAX_YCOORDINATE_BITS_LEN / 8];
        if (ulBits == 256) {
            int len = ECC_MAX_XCOORDINATE_BITS_LEN / 8 / 2;
            System.arraycopy(XBytes, XBytes.length - len, x, x.length - len, len);
            System.arraycopy(YBytes, YBytes.length - len, y, y.length - len, len);
        } else if (ulBits == 512) {
            int len = ECC_MAX_XCOORDINATE_BITS_LEN / 8;
            System.arraycopy(XBytes, XBytes.length - len, x, x.length - len, len);
            System.arraycopy(YBytes, YBytes.length - len, y, y.length - len, len);
        }

        this.bits = ulBits;
    }

    public byte[] getBytes() {
        byte[] bitLenBytes = intToBytes(bits, ByteOrder.LITTLE_ENDIAN);
        byte[] xBytes = x;
        byte[] yBytes = y;
        byte[] result = new byte[bitLenBytes.length + xBytes.length + yBytes.length];
        System.arraycopy(bitLenBytes, 0, result, 0, bitLenBytes.length);
        System.arraycopy(xBytes, 0, result, bitLenBytes.length, xBytes.length);
        System.arraycopy(yBytes, 0, result, bitLenBytes.length + xBytes.length, yBytes.length);
        return result;
    }
}
